package org.ohos.rajawali3d.examples.examples.postprocessing;

import ohos.app.Context;
import ohos.opengl.Color;
import org.ohos.rajawali3d.examples.examples.AExampleFragment;
import org.rajawali3d.animation.Animation;
import org.rajawali3d.animation.RotateOnAxisAnimation;
import org.rajawali3d.lights.DirectionalLight;
import org.rajawali3d.materials.Material;
import org.rajawali3d.materials.methods.DiffuseMethod;
import org.rajawali3d.math.vector.Vector3;
import org.rajawali3d.postprocessing.PostProcessingManager;
import org.rajawali3d.postprocessing.effects.BloomEffect;
import org.rajawali3d.postprocessing.passes.BlendPass;
import org.rajawali3d.postprocessing.passes.RenderPass;
import org.rajawali3d.primitives.Cube;
import org.rajawali3d.util.RajLog;

import java.util.Random;

public class BloomEffectFragment extends AExampleFragment {

    @Override
    public AExampleRenderer createRenderer() {
        return new BloomEffectRenderer(getContext(), this);
    }

    public static final class BloomEffectRenderer extends AExampleRenderer {
        private PostProcessingManager mEffects;

        public BloomEffectRenderer(Context context, AExampleFragment fragment) {
            super(context, fragment);
        }

        @Override
        public void initScene() {
            DirectionalLight light = new DirectionalLight();
            light.setPower(1);
            light.setLookAt(0, 0, -1);
            light.enableLookAt();
            getCurrentScene().setBackgroundColor(Color.BLACK);
            getCurrentScene().addLight(light);

            //
            // -- Create a material for all cubes
            //

            Material material = new Material();
            material.enableLighting(true);
            material.setDiffuseMethod(new DiffuseMethod.Lambert());

            getCurrentCamera().setZ(10);

            Random random = new Random();

            //
            // -- Generate cubes with random x, y, z
            //

            for (int i = 0; i < 20; i++) {
                Cube cube = new Cube(1);
                cube.setPosition(-5 + random.nextFloat() * 10,
                        -5 + random.nextFloat() * 10, random.nextFloat() * -10);
                cube.setMaterial(material);
                cube.setColor(0x666666 + random.nextInt(0x999999));
                getCurrentScene().addChild(cube);

                Vector3 randomAxis = new Vector3(random.nextFloat(),
                        random.nextFloat(), random.nextFloat());
                randomAxis.normalize();

                RotateOnAxisAnimation anim = new RotateOnAxisAnimation(randomAxis,
                        360);
                anim.setTransformable3D(cube);
                anim.setDurationMilliseconds(3000 + (int) (random.nextDouble() * 5000));
                anim.setRepeatMode(Animation.RepeatMode.INFINITE);
                getCurrentScene().registerAnimation(anim);
                anim.play();
            }

            //
            // -- Create a post processing manager. We can add multiple passes to this.
            //

            mEffects = new PostProcessingManager(this);
            RenderPass renderPass = new RenderPass(getCurrentScene(), getCurrentCamera(), 0);
            mEffects.addPass(renderPass);

            BloomEffect bloomEffect = new BloomEffect(getCurrentScene(), getCurrentCamera(), getViewportWidth(), getViewportHeight(), 0x111111, 0xffffff, BlendPass.BlendMode.SCREEN);
            mEffects.addEffect(bloomEffect);

            bloomEffect.setRenderToScreen(true);

            RajLog.i("Viewport: " + getViewportWidth() + ", " + getViewportHeight());
        }

        @Override
        public void onRender(final long elapsedTime, final double deltaTime) {
            mEffects.render(elapsedTime, deltaTime);
        }
    }
}
